/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package generator.collections;

import generator.statements.Statement;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Random;

/**
 * SQL tables base class.
 *
 * @author Marek Snopkowski <snpy@snpy.info>
 * @version 12.04.2008
 */
abstract public class AbstractTable<T> implements Iterable<T>
{
    protected HashMap<Integer, T> rows = new HashMap<Integer, T>(10);
    
    private static int id;
    
    /**
     * Generate locally unique id number.
     * 
     * @return Unique number.
     */
    public static int autoincrement()
    {
        return id++;
    }
    
    abstract public String getTableName();
    
    public Iterator<T> iterator()
    {
        return rows.values().iterator();
    }
    
    protected AbstractTable() {}
    
    final public int count()
    {
        return rows.size();
    }
    
    @Override
    public String toString()
    {
//        String tableName = this.getClass().getName();
//        return tableName.substring(tableName.lastIndexOf('.') + 1 );
        return this.getTableName();
    }
    
    public String prepareInsert()
    {
        Statement stmt = (Statement)selectRandom();
        if (null == stmt)
        {
            return "";
        }
        
        return String.format("INSERT INTO [%s] (%s)\nVALUES", 
                this, stmt.getFieldsNameSet());
    }
    
    final public T selectRandom()
    {
        if (isEmpty())
            return null;
        
        return (T)rows.values().toArray()[(new Random()).nextInt(count())];
    }
    
    final public boolean isEmpty()
    {
        return rows.isEmpty();
    }
    
    final public T delete(int idx)
    {
        T stmt = select(idx);
        rows.remove(idx);
        return stmt;
    }
    
    final public T delete(T stmt)
    {
        return delete(((Statement)stmt).getId());
    }
    
    final public T select(int idx)
    {
        return rows.get(idx);
    }
    
    final public T select(T stmt)
    {
        return select(((Statement)stmt).getId());
    }
    
    final public T insert(int idx, T stmt)
    {
        if (rows.containsKey(idx)
                || null == stmt)
            return null;
        
        return rows.put(idx, stmt);
    }
    
    final public T insert(T stmt)
    {
        return null == stmt
                ? null
                : insert(((Statement)stmt).getId(), stmt);
    }
    
    final public T update(int idx, T stmt)
    {
        return rows.put(idx, stmt);
    }
    
    final public T update(T stmt)
    {
        return update(((Statement)stmt).getId(), stmt);
    }
    
    final public T replace(int idx, T stmt)
    {
        if (!rows.containsKey(idx))
            return null;
        
        return rows.put(idx, stmt);
    }
        
    final public T replace(T stmt)
    {
        return replace(((Statement)stmt).getId(), stmt);
    }
}
